home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / wwbbs31_source.lha / WWBBS / WWBBSSrc / serial.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  16KB  |  430 lines

  1. #include <exec/types.h>
  2. #include <exec/exec.h>
  3. #include <dos/dos.h>
  4. #include <dos/dostags.h>
  5. #include <intuition/intuition.h>
  6. #include <libraries/wwbbs.h>
  7. #include <devices/serial.h>
  8. #include <ctype.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "wwbbs.h"
  14.  
  15. #include "wwbbs_settings.h"
  16.  
  17. #include "wwbbs_lib.h"
  18.  
  19. #include "libs.h"
  20.  
  21. #include "Data:Programs/Include/wwbbs_commands.h"
  22.  
  23. #include "Data:Programs/Include/OwnDevUnit.h"
  24.  
  25. LONG __saveds SerialProc()
  26.     {
  27.         struct ConfirmationMessage *msg;
  28.         struct CommandMessage *qmsg=NULL;
  29.         struct Process *proc;
  30.         proc=(struct Process *) FindTask(NULL);
  31.         WaitPort(&proc->pr_MsgPort);
  32.         if(msg=(struct ConfirmationMessage *) GetMsg(&proc->pr_MsgPort))
  33.             {
  34.                 BYTE name[64],command_name[64],id[33];
  35.                 struct MsgPort *port,*command_port;
  36.                 BOOL ok=TRUE;
  37.                 strcpy(id,msg->cm_ID);
  38.                 sprintf(name,"WWBBS Serial.%s",id);
  39.                 if(!(port=CreatePort(name,0)))
  40.                     ok=FALSE;
  41.                 sprintf(command_name,"WWBBS Serial Command.%s",id);
  42.                 if(!(command_port=CreatePort(command_name,0)))
  43.                     ok=FALSE;
  44.                 msg->cm_Return=ok;
  45.                 ReplyMsg((struct Message *) msg);
  46.                 if(ok)
  47.                     {
  48.                         struct Libraries *libs;
  49.                         if(libs=OpenLibraries())
  50.                             {
  51.                                 struct Library *OwnDevUnitBase;
  52.                                 BYTE serial_device[33];
  53.                                 ULONG serial_unit=0,serial_buffersize=0,serial_baud=0;
  54.                                 BOOL serial_handshaking=FALSE,frontend=FALSE;
  55.                                 strcpy(serial_device,"");
  56.                                 OwnDevUnitBase=OpenLibrary(ODU_NAME,0);
  57.                                 GetConfigTags(CFGTAG_Path,"Nodes",CFGTAG_Name,id,
  58.                                     NDTAG_Device,serial_device,
  59.                                     NDTAG_Unit,&serial_unit,
  60.                                     NDTAG_BufferSize,&serial_buffersize,
  61.                                     NDTAG_Baud,&serial_baud,
  62.                                     NDTAG_Handshaking,&serial_handshaking,
  63.                                     NDTAG_FrontEnd,&frontend,
  64.                                     TAG_END);
  65.                                 {
  66.                                     struct MsgPort *SerialMP=NULL;
  67.                                     struct IOExtSer *SerialIO=NULL;
  68.                                     BOOL seriallocked=FALSE;
  69.                                     BYTE signal=-1;
  70.                                     struct CommandMessage *cmsg=NULL;
  71.                                     ULONG cdata=NULL;
  72.                                     ULONG mask;
  73.                                     BOOL serialopen=FALSE,kg=TRUE;
  74.                                     while(kg)
  75.                                         {
  76.                                             {
  77.                                                 ULONG waitmask=NULL;
  78.                                                 waitmask|=1 << port->mp_SigBit;
  79.                                                 if(cmsg)
  80.                                                     waitmask|=(1 << SerialMP->mp_SigBit) | (1 << command_port->mp_SigBit);
  81.                                                 if(seriallocked)
  82.                                                     waitmask|=(1 << signal);
  83.                                                 mask=Wait(waitmask);
  84.                                             }
  85.                                             if(mask & (1 << port->mp_SigBit))
  86.                                                 {
  87.                                                     struct CommandMessage *msg;
  88.                                                     while(kg && (msg=(struct CommandMessage *) GetMsg(port)))
  89.                                                         {
  90.                                                             ULONG data;
  91.                                                             data=msg->cm_Data;
  92.                                                             msg->cm_Data=NULL;
  93.                                                             switch(msg->cm_Command)
  94.                                                                 {
  95.                                                                     case SERCMD_Quit:
  96.                                                                         msg->cm_Data=TRUE;
  97.                                                                         qmsg=msg;
  98.                                                                         kg=FALSE;
  99.                                                                         break;
  100.                                                                     case SERCMD_Open:
  101.                                                                         {
  102.                                                                             SerialMP=NULL;
  103.                                                                             SerialIO=NULL;
  104.                                                                             if(strlen(serial_device) && serial_buffersize && serial_baud)
  105.                                                                                 {
  106.                                                                                     if(OwnDevUnitBase && !frontend)
  107.                                                                                         {
  108.                                                                                             seriallocked=FALSE;
  109.                                                                                             signal=-1;
  110.                                                                                             if( (signal=AllocSignal(-1)) != -1)
  111.                                                                                                 {
  112.                                                                                                     if(!LockDevUnit(serial_device,serial_unit,name,signal))
  113.                                                                                                         seriallocked=TRUE;
  114.                                                                                                     else
  115.                                                                                                         {
  116.                                                                                                             FreeSignal(signal);
  117.                                                                                                             signal=-1;
  118.                                                                                                         }
  119.                                                                                                 }
  120.                                                                                         }
  121.                                                                                     if(!OwnDevUnitBase || frontend || seriallocked)
  122.                                                                                         {
  123.                                                                                             if(SerialMP=CreateMsgPort())
  124.                                                                                                 {
  125.                                                                                                     if(SerialIO=(struct IOExtSer *) CreateIORequest(SerialMP,sizeof(struct IOExtSer)))
  126.                                                                                                         {
  127.                                                                                                             if(serial_handshaking)
  128.                                                                                                                 SerialIO->io_SerFlags|=SERF_7WIRE;
  129.                                                                                                             else
  130.                                                                                                                 SerialIO->io_SerFlags&=~SERF_7WIRE;
  131.                                                                                                             SerialIO->io_SerFlags|=SERF_SHARED;
  132.                                                                                                             if(!OpenDevice(serial_device,serial_unit,(struct IORequest *) SerialIO,0))
  133.                                                                                                                 {
  134.                                                                                                                     serialopen=TRUE;
  135.                                                                                                                     msg->cm_Data=TRUE;
  136.                                                                                                                 }
  137.                                                                                                         }
  138.                                                                                                 }
  139.                                                                                             if(!serialopen)
  140.                                                                                                 {
  141.                                                                                                     if(SerialIO) DeleteIORequest((struct IORequest *) SerialIO);
  142.                                                                                                     if(SerialMP) DeleteMsgPort(SerialMP);
  143.                                                                                                 }
  144.                                                                                         }
  145.                                                                                 }
  146.                                                                         }
  147.                                                                         break;
  148.                                                                     case SERCMD_Close:
  149.                                                                         if(serialopen)
  150.                                                                             {
  151.                                                                                 if(cmsg)
  152.                                                                                     {
  153.                                                                                         if(!CheckIO((struct IORequest *) SerialIO))
  154.                                                                                             AbortIO((struct IORequest *) SerialIO);
  155.                                                                                         WaitIO((struct IORequest *) SerialIO);
  156.                                                                                         ReplyMsg((struct Message *) cmsg);
  157.                                                                                         cmsg=NULL;
  158.                                                                                     }
  159.                                                                                 CloseDevice((struct IORequest *) SerialIO);
  160.                                                                                 DeleteIORequest((struct IORequest *) SerialIO);
  161.                                                                                 DeleteMsgPort(SerialMP);
  162.                                                                                 serialopen=FALSE;
  163.                                                                                 if(OwnDevUnitBase && !frontend)
  164.                                                                                     {
  165.                                                                                         FreeDevUnit(serial_device,serial_unit);
  166.                                                                                         FreeSignal(signal);
  167.                                                                                         signal=-1;
  168.                                                                                         seriallocked=FALSE;
  169.                                                                                     }
  170.                                                                             }
  171.                                                                         break;
  172.                                                                     case SERCMD_Read:
  173.                                                                         if(!cmsg && data)
  174.                                                                             {
  175.                                                                                 APTR buffer=NULL;
  176.                                                                                 ULONG size=0;
  177.                                                                                 {
  178.                                                                                     struct TagItem *tag;
  179.                                                                                     if(tag=FindTagItem(SERREADTAG_Buffer,(struct TagItem *) data))
  180.                                                                                         buffer=(APTR) tag->ti_Data;
  181.                                                                                     if(tag=FindTagItem(SERREADTAG_Size,(struct TagItem *) data))
  182.                                                                                         size=tag->ti_Data;
  183.                                                                                 }
  184.                                                                                 if(buffer && size)
  185.                                                                                     {
  186.                                                                                         ULONG count;
  187.                                                                                         SerialIO->IOSer.io_Command=SDCMD_QUERY;
  188.                                                                                         DoIO((struct IORequest *) SerialIO);
  189.                                                                                         count=SerialIO->IOSer.io_Actual;
  190.                                                                                         if(count)
  191.                                                                                             {
  192.                                                                                                 SerialIO->IOSer.io_Length=(count>size) ? size : count;
  193.                                                                                                 SerialIO->IOSer.io_Data=buffer;
  194.                                                                                                 SerialIO->IOSer.io_Command=CMD_READ;
  195.                                                                                                 DoIO((struct IORequest *) SerialIO);
  196.                                                                                                 msg->cm_Data=SerialIO->IOSer.io_Actual;
  197.                                                                                             }
  198.                                                                                     }
  199.                                                                             }
  200.                                                                         break;
  201.                                                                     case SERCMD_Write:
  202.                                                                         if(!cmsg && data)
  203.                                                                             {
  204.                                                                                 APTR buffer=NULL;
  205.                                                                                 ULONG size=0;
  206.                                                                                 {
  207.                                                                                     struct TagItem *tag;
  208.                                                                                     if(tag=FindTagItem(SERWRITETAG_Buffer,(struct TagItem *) data))
  209.                                                                                         buffer=(APTR) tag->ti_Data;
  210.                                                                                     if(tag=FindTagItem(SERWRITETAG_Size,(struct TagItem *) data))
  211.                                                                                         size=tag->ti_Data;
  212.                                                                                 }
  213.                                                                                 if(buffer && size)
  214.                                                                                     {
  215.                                                                                         SerialIO->IOSer.io_Data=buffer;
  216.                                                                                         SerialIO->IOSer.io_Length=size;
  217.                                                                                         SerialIO->IOSer.io_Command=CMD_WRITE;
  218.                                                                                         DoIO((struct IORequest *) SerialIO);
  219.                                                                                         msg->cm_Data=(ULONG) TRUE;
  220.                                                                                     }
  221.                                                                             }
  222.                                                                         break;
  223.                                                                     case SERCMD_Wait:
  224.                                                                         if(!cmsg && data)
  225.                                                                             {
  226.                                                                                 APTR buffer=NULL;
  227.                                                                                 ULONG size=0;
  228.                                                                                 {
  229.                                                                                     struct TagItem *tag;
  230.                                                                                     if(tag=FindTagItem(SERWAITTAG_Buffer,(struct TagItem *) data))
  231.                                                                                         buffer=(APTR) tag->ti_Data;
  232.                                                                                     if(tag=FindTagItem(SERWAITTAG_Size,(struct TagItem *) data))
  233.                                                                                         size=tag->ti_Data;
  234.                                                                                 }
  235.                                                                                 if(buffer && size)
  236.                                                                                     {
  237.                                                                                         cmsg=msg;
  238.                                                                                         cdata=data;
  239.                                                                                         SerialIO->IOSer.io_Length=1;
  240.                                                                                         SerialIO->IOSer.io_Data=buffer;
  241.                                                                                         SerialIO->IOSer.io_Command=CMD_READ;
  242.                                                                                         SendIO((struct IORequest *) SerialIO);
  243.                                                                                     }
  244.                                                                             }
  245.                                                                         break;
  246.                                                                     case SERCMD_Abort:
  247.                                                                         if(cmsg)
  248.                                                                             {
  249.                                                                                 if(!CheckIO((struct IORequest *) SerialIO))
  250.                                                                                     AbortIO((struct IORequest *) SerialIO);
  251.                                                                                 WaitIO((struct IORequest *) SerialIO);
  252.                                                                                 ReplyMsg((struct Message *) cmsg);
  253.                                                                                 cmsg=NULL;
  254.                                                                             }
  255.                                                                         break;
  256.                                                                     case SERCMD_SetBaud:
  257.                                                                         if(!cmsg && data)
  258.                                                                             {
  259.                                                                                 BOOL resetbaud=FALSE;
  260.                                                                                 ULONG newbaud=0;
  261.                                                                                 {
  262.                                                                                     struct TagItem *tag;
  263.                                                                                     if(tag=FindTagItem(SERSETBAUDTAG_ResetBaud,(struct TagItem *) data))
  264.                                                                                         resetbaud=tag->ti_Data;
  265.                                                                                     if(tag=FindTagItem(SERSETBAUDTAG_NewBaud,(struct TagItem *) data))
  266.                                                                                         newbaud=tag->ti_Data;
  267.                                                                                 }
  268.                                                                                 SerialIO->io_RBufLen=serial_buffersize;
  269.                                                                                 SerialIO->io_ReadLen=8;
  270.                                                                                 SerialIO->io_WriteLen=8;
  271.                                                                                 SerialIO->io_StopBits=1;
  272.                                                                                 if(resetbaud)
  273.                                                                                     {
  274.                                                                                         SerialIO->io_Baud=serial_baud;
  275.                                                                                         msg->cm_Data=serial_baud;
  276.                                                                                     }
  277.                                                                                 else
  278.                                                                                     {
  279.                                                                                         if(newbaud)
  280.                                                                                             {
  281.                                                                                                 SerialIO->io_Baud=newbaud;
  282.                                                                                                 msg->cm_Data=newbaud;
  283.                                                                                             }
  284.                                                                                     }
  285.                                                                                 SerialIO->io_SerFlags|=SERF_RAD_BOOGIE;
  286.                                                                                 SerialIO->IOSer.io_Command=SDCMD_SETPARAMS;
  287.                                                                                 DoIO((struct IORequest *) SerialIO);
  288.                                                                             }
  289.                                                                         break;
  290.                                                                     case SERCMD_Carrier:
  291.                                                                         SerialIO->IOSer.io_Command=SDCMD_QUERY;
  292.                                                                         DoIO((struct IORequest *) SerialIO);
  293.                                                                         if(!(SerialIO->io_Status & (1L << 5)))
  294.                                                                             msg->cm_Data=TRUE;
  295.                                                                         break;
  296.                                                                     case SERCMD_Query:
  297.                                                                         if(!cmsg)
  298.                                                                             {
  299.                                                                                 SerialIO->IOSer.io_Command=SDCMD_QUERY;
  300.                                                                                 DoIO((struct IORequest *) SerialIO);
  301.                                                                                 msg->cm_Data=SerialIO->IOSer.io_Actual;
  302.                                                                             }
  303.                                                                         break;
  304.                                                                 }
  305.                                                             if(!qmsg && cmsg!=msg)
  306.                                                                 ReplyMsg((struct Message *) msg);
  307.                                                         }
  308.                                                 }
  309.                                             if(seriallocked)
  310.                                                 {
  311.                                                     if(mask & (1 << signal))
  312.                                                         {
  313.                                                             FreeDevUnit(serial_device,serial_unit);
  314.                                                             Delay(50L);
  315.                                                             while(LockDevUnit(serial_device,serial_unit,name,signal))
  316.                                                                 ;
  317.                                                         }
  318.                                                 }
  319.                                             if(serialopen)
  320.                                                 {
  321.                                                     if(mask & (1 << SerialMP->mp_SigBit))
  322.                                                         {
  323.                                                             if(CheckIO((struct IORequest *) SerialIO))
  324.                                                                 {
  325.                                                                     WaitIO((struct IORequest *) SerialIO);
  326.                                                                     if(cmsg && cdata)
  327.                                                                         {
  328.                                                                             BYTE *buffer=NULL;
  329.                                                                             ULONG size=NULL;
  330.                                                                             {
  331.                                                                                 struct TagItem *tag;
  332.                                                                                 if(tag=FindTagItem(SERWAITTAG_Buffer,(struct TagItem *) cdata))
  333.                                                                                     buffer=(APTR) tag->ti_Data;
  334.                                                                                 if(tag=FindTagItem(SERWAITTAG_Size,(struct TagItem *) cdata))
  335.                                                                                     size=tag->ti_Data;
  336.                                                                             }
  337.                                                                             if(size>1)
  338.                                                                                 {
  339.                                                                                     ULONG count;
  340.                                                                                     SerialIO->IOSer.io_Command=SDCMD_QUERY;
  341.                                                                                     DoIO((struct IORequest *) SerialIO);
  342.                                                                                     count=SerialIO->IOSer.io_Actual;
  343.                                                                                     if(count)
  344.                                                                                         {
  345.                                                                                             SerialIO->IOSer.io_Length=(count>size-1) ? size-1 : count;
  346.                                                                                             SerialIO->IOSer.io_Data=(APTR) &buffer[1];
  347.                                                                                             SerialIO->IOSer.io_Command=CMD_READ;
  348.                                                                                             DoIO((struct IORequest *) SerialIO);
  349.                                                                                             cmsg->cm_Data=SerialIO->IOSer.io_Actual+1;
  350.                                                                                         }
  351.                                                                                     else
  352.                                                                                         cmsg->cm_Data=1;
  353.                                                                                 }
  354.                                                                             else
  355.                                                                                 cmsg->cm_Data=1;
  356.                                                                             ReplyMsg((struct Message *) cmsg);
  357.                                                                             cmsg=NULL;
  358.                                                                         }
  359.                                                                 }
  360.                                                         }
  361.                                                     if(mask & (1 << command_port->mp_SigBit))
  362.                                                         {
  363.                                                             struct CommandMessage *msg;
  364.                                                             ULONG data;
  365.                                                             while(msg=(struct CommandMessage *) GetMsg(command_port))
  366.                                                                 {
  367.                                                                     data=msg->cm_Data;
  368.                                                                     msg->cm_Data=NULL;
  369.                                                                     switch(msg->cm_Command)
  370.                                                                         {
  371.                                                                             case NDCMD_Quit:
  372.                                                                                 SetStatusTags(STTAG_Name,id,STTAG_Panic,TRUE,TAG_END);
  373.                                                                                 break;
  374.                                                                             case NDCMD_Panic:
  375.                                                                                 SetStatusTags(STTAG_Name,id,STTAG_Panic,TRUE,TAG_END);
  376.                                                                                 msg->cm_Data=TRUE;
  377.                                                                                 break;
  378.                                                                             case NDCMD_Page:
  379.                                                                                 break;
  380.                                                                         }
  381.                                                                     ReplyMsg((struct Message *) msg);
  382.                                                                 }
  383.                                                             if(cmsg)
  384.                                                                 {
  385.                                                                     if(!CheckIO((struct IORequest *) SerialIO))
  386.                                                                         AbortIO((struct IORequest *) SerialIO);
  387.                                                                     WaitIO((struct IORequest *) SerialIO);
  388.                                                                     ReplyMsg((struct Message *) cmsg);
  389.                                                                     cmsg=NULL;
  390.                                                                 }
  391.                                                         }
  392.                                                 }
  393.                                         }
  394.                                     if(serialopen)
  395.                                         {
  396.                                             if(cmsg)
  397.                                                 {
  398.                                                     if(!CheckIO((struct IORequest *) SerialIO))
  399.                                                         AbortIO((struct IORequest *) SerialIO);
  400.                                                     WaitIO((struct IORequest *) SerialIO);
  401.                                                     ReplyMsg((struct Message *) cmsg);
  402.                                                     cmsg=NULL;
  403.                                                 }
  404.                                             CloseDevice((struct IORequest *) SerialIO);
  405.                                             DeleteIORequest((struct IORequest *) SerialIO);
  406.                                             DeleteMsgPort(SerialMP);
  407.                                             if(OwnDevUnitBase && !frontend)
  408.                                                 {
  409.                                                     FreeDevUnit(serial_device,serial_unit);
  410.                                                     FreeSignal(signal);
  411.                                                     signal=-1;
  412.                                                     seriallocked=FALSE;
  413.                                                 }
  414.                                         }
  415.                                 }
  416.                                 if(OwnDevUnitBase) CloseLibrary(OwnDevUnitBase);
  417.                                 CloseLibraries(libs);
  418.                             }
  419.                     }
  420.                 if(command_port) DeletePort(command_port);
  421.                 if(port) DeletePort(port);
  422.             }
  423.         if(qmsg)
  424.             {
  425.                 Forbid();
  426.                 ReplyMsg((struct Message *) qmsg);
  427.             }
  428.         return(0);
  429.     }
  430.